
local img = {}

local game_2048 = {
    {0,0,0,0},
    {0,0,0,0},
    {0,0,0,0},
    {0,0,0,0}
}

--0 normal 1 win 2 die
local game_state = 0

local function cls()
    for i=1,4 do
        for j=1,4 do
            game_2048[i][j]=0
        end
    end
end

local function get_all_empty()
    local x={}
    for i=1,4 do
        local y=game_2048[i]
        for j=1,4 do
            if y[j] == 0 then
                table.insert(x, {i,j})
            end
        end
    end
    return x
end

local function fill2or4()
    --1/4概率生成4 (1表示2 2表示4)
    if math.random(4)==1 then
        return 2
    end
    return 1
end

local function fill_num(x)
    local a=get_all_empty()
    local l=table.getn(a)
    if l==0 then
        game_state=2
    else
        i=math.random(l)
        if x==1 then
            game_2048[a[i][1]][a[i][2]]=1
        else
            game_2048[a[i][1]][a[i][2]]=fill2or4()
        end
    end
end

local function new_game()
    game_state=0
    cls()
    fill_num(1)
    fill_num(1)
    fill_num(1)
end

local function init()
    math.randomseed(os.time())
    new_game()
    img['0'] = love.graphics.newImage( "data/img/2048/0.jpg" )
    img['1'] = love.graphics.newImage( "data/img/2048/2.jpg" )
    img['2'] = love.graphics.newImage( "data/img/2048/4.jpg" )
    img['3'] = love.graphics.newImage( "data/img/2048/8.jpg" )
    img['4'] = love.graphics.newImage( "data/img/2048/16.jpg" )
    img['5'] = love.graphics.newImage( "data/img/2048/32.jpg" )
    img['6'] = love.graphics.newImage( "data/img/2048/64.jpg" )
    img['7'] = love.graphics.newImage( "data/img/2048/128.jpg" )
    img['8'] = love.graphics.newImage( "data/img/2048/256.jpg" )
    img['9'] = love.graphics.newImage( "data/img/2048/512.jpg" )
    img['10'] = love.graphics.newImage( "data/img/2048/1024.jpg" )
    img['11'] = love.graphics.newImage( "data/img/2048/2048.jpg" )
end

local function x_get_num(l)
    local r={}
    for _,x in pairs(l) do
        if x~=0 then
            table.insert(r, x)
        end
    end
    return r
end
local function x_merge_num(l)
    local ll=table.getn(l)
    if ll==0 then
        return {0,0,0,0}
    elseif ll==1 then
        return {l[1],0,0,0}
    elseif ll==2 then
        if l[1]==l[2] then
            return {l[1]+1,0,0,0}
        else
            return {l[1],l[2],0,0}
        end
    elseif ll==3 then
        if l[1]==l[2] then
            return {l[1]+1,l[3],0,0}
        elseif l[2]==l[3] then
            return {l[1],l[2]+1,0,0}
        else
            return {l[1],l[2],l[3],0}
        end
    elseif ll==4 then
        if l[1]==l[2] then
            return {l[1]+1,l[3],l[4],0}
        elseif l[2]==l[3] then
            return {l[1],l[2]+1,l[4],0}
        elseif l[3]==l[4] then
            return {l[1],l[2],l[3]+1,0}
        else
            return {l[1],l[2],l[3],l[4]}
        end
    end

end

local function move_up()
    local l1={game_2048[1][1],game_2048[1][2],game_2048[1][3],game_2048[1][4]}
    local l2={game_2048[2][1],game_2048[2][2],game_2048[2][3],game_2048[2][4]}
    local l3={game_2048[3][1],game_2048[3][2],game_2048[3][3],game_2048[3][4]}
    local l4={game_2048[4][1],game_2048[4][2],game_2048[4][3],game_2048[4][4]}
    local p1=x_merge_num(x_get_num(l1))
    local p2=x_merge_num(x_get_num(l2))
    local p3=x_merge_num(x_get_num(l3))
    local p4=x_merge_num(x_get_num(l4))
    game_2048[1]={p1[1],p1[2],p1[3],p1[4]}
    game_2048[2]={p2[1],p2[2],p2[3],p2[4]}
    game_2048[3]={p3[1],p3[2],p3[3],p3[4]}
    game_2048[4]={p4[1],p4[2],p4[3],p4[4]}
end
local function move_down()
    local l1={game_2048[1][4],game_2048[1][3],game_2048[1][2],game_2048[1][1]}
    local l2={game_2048[2][4],game_2048[2][3],game_2048[2][2],game_2048[2][1]}
    local l3={game_2048[3][4],game_2048[3][3],game_2048[3][2],game_2048[3][1]}
    local l4={game_2048[4][4],game_2048[4][3],game_2048[4][2],game_2048[4][1]}
    local p1=x_merge_num(x_get_num(l1))
    local p2=x_merge_num(x_get_num(l2))
    local p3=x_merge_num(x_get_num(l3))
    local p4=x_merge_num(x_get_num(l4))
    game_2048[1]={p1[4],p1[3],p1[2],p1[1]}
    game_2048[2]={p2[4],p2[3],p2[2],p2[1]}
    game_2048[3]={p3[4],p3[3],p3[2],p3[1]}
    game_2048[4]={p4[4],p4[3],p4[2],p4[1]}
end
local function move_left()
    local l1={game_2048[1][1],game_2048[2][1],game_2048[3][1],game_2048[4][1]}
    local l2={game_2048[1][2],game_2048[2][2],game_2048[3][2],game_2048[4][2]}
    local l3={game_2048[1][3],game_2048[2][3],game_2048[3][3],game_2048[4][3]}
    local l4={game_2048[1][4],game_2048[2][4],game_2048[3][4],game_2048[4][4]}
    local p1=x_merge_num(x_get_num(l1))
    local p2=x_merge_num(x_get_num(l2))
    local p3=x_merge_num(x_get_num(l3))
    local p4=x_merge_num(x_get_num(l4))
    game_2048[1]={p1[1],p2[1],p3[1],p4[1]}
    game_2048[2]={p1[2],p2[2],p3[2],p4[2]}
    game_2048[3]={p1[3],p2[3],p3[3],p4[3]}
    game_2048[4]={p1[4],p2[4],p3[4],p4[4]}
end
local function move_right()
    local l1={game_2048[4][1],game_2048[3][1],game_2048[2][1],game_2048[1][1]}
    local l2={game_2048[4][2],game_2048[3][2],game_2048[2][2],game_2048[1][2]}
    local l3={game_2048[4][3],game_2048[3][3],game_2048[2][3],game_2048[1][3]}
    local l4={game_2048[4][4],game_2048[3][4],game_2048[2][4],game_2048[1][4]}
    local p1=x_merge_num(x_get_num(l1))
    local p2=x_merge_num(x_get_num(l2))
    local p3=x_merge_num(x_get_num(l3))
    local p4=x_merge_num(x_get_num(l4))
    game_2048[1]={p1[4],p2[4],p3[4],p4[4]}
    game_2048[2]={p1[3],p2[3],p3[3],p4[3]}
    game_2048[3]={p1[2],p2[2],p3[2],p4[2]}
    game_2048[4]={p1[1],p2[1],p3[1],p4[1]}
end

local function draw()
    love.graphics.setColor(255, 255, 0, 255)
    love.graphics.print("2048 （1：new game 2:return）", 200, 30)
    love.graphics.reset()

    if game_state==1 then
        love.graphics.print("Win", 200, 80)
    elseif game_state==2 then
        love.graphics.print("Game over", 200, 80)
    end

    for i=1,4 do
        local n="%d"
        for j=1,4 do
            love.graphics.draw(img[n:format(game_2048[i][j])], 70+i*110, 20+j*110)
        end
    end
end

local function keypressed(key)
    if key == '1' then
        new_game()
    elseif key == '2' then
        local s = require('engine/scene')
        s.retreat()
    elseif game_state==0 then
        if key == 'up' then
            move_up()
            fill_num()
        elseif key == 'down' then
            move_down()
            fill_num()
        elseif key == 'left' then
            move_left()
            fill_num()
        elseif key == 'right' then
            move_right()
            fill_num()
        end
    end
end

local x = {}
x.init = init
x.draw = draw
x.keypressed = keypressed
return x
